package week1;

import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.QuickUnionUF;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.WeightedQuickUnionUF;

/**
 * Created by dyc on 2016/10/14.
 */
public class Percolation {
    private boolean[] sites;
    private WeightedQuickUnionUF uf;
    private int n;

    public Percolation(int n){
        if (n <= 0)
            throw new IllegalArgumentException();
        this.n = n;
        sites = new boolean[n * n];
        uf = new WeightedQuickUnionUF(n * n);
    }

    private int coordination2Index(int row,int col){
        return (row - 1) * n + (col - 1);
    }

    private boolean checkArgs(int i,int j){
        return i > 0 && i <= n && j > 0 && j <= n;
    }

    public void open(int i,int j){
        if (!checkArgs(i,j))
            throw new IndexOutOfBoundsException();
        if (isOpen(i,j))
            return;
        int index = coordination2Index(i,j);
        sites[index] = true;
        for (int  row =i - 1; row <= i + 1; row++){
            for (int col = j - 1; col <= j + 1; col++){
                if (!checkArgs(row,col))
                    continue;
                if (row != i && col != j)
                    continue;
                if (row == i && col == j)
                    continue;
                int neighbourIndex = coordination2Index(row,col);
                if (isOpen(row,col) && !uf.connected(neighbourIndex,index))
                    uf.union(neighbourIndex,index);
            }
        }
    }

    public boolean isOpen(int i,int j){
        if (!checkArgs(i,j))
            throw new IndexOutOfBoundsException();
        int index = coordination2Index(i,j);
        return sites[index];
    }

    public boolean isFull(int i,int j){
        if (!isOpen(i,j))
            return false;
        int index = coordination2Index(i,j);
        for (int k = 0; k < n; k++){
            if (uf.find(k) == uf.find(index)){
                return true;
            }
        }
        return false;
    }

    public boolean percolates(){
        for (int i = 1; i <= n; i++){
            if (isFull(n,i))
                return true;
        }
        return false;
    }
}
